home *** CD-ROM | disk | FTP | other *** search
- ===========================================================================
- BBS: Canada Remote Systems
- Date: 07-03-93 (11:56) Number: 29412
- From: KELD R. HANSEN Refer#: NONE
- To: JON JASIUNAS Recvd: NO
- Subj: Re: Self-modifying .EXEs Conf: (1221) F-PASCAL
- ---------------------------------------------------------------------------
- In a message dated 28 Jun 93, Jon Jasiunas (1:273/216.0) wrote:
-
- > Here's the code I use for my self-modifying .EXEs. I've used it
- > successfully in several applications.
-
- It works fine (I have one similar of my own), but it doesn't take care of DPMI
- programs and won't work if your "customer" PKLITEs the program.
-
- TYPE
- ExeHeaderDOS = RECORD
- { 00 } Signature : ARRAY[1..2] OF CHAR;
- { 02 } LastPageSize : WORD;
- { 04 } Pages : WORD;
- { 06 } RelocItems : WORD;
- { 08 } HeaderSizePara : WORD;
- { 0A } MinMemPara : WORD;
- { 0C } MaxMemPara : WORD;
- { 0E } EntrySS : WORD;
- { 10 } EntrySP : WORD;
- { 12 } CheckSum : WORD;
- { 14 } EntryIP : WORD;
- { 16 } EntryCS : WORD;
- { 18 } FirstRelocItemOfs : WORD;
- { 1A } OverlayNumber : WORD;
- Reserved : ARRAY[$1C..$23] OF BYTE;
- { 24 } IdentifierOEM : WORD;
- { 26 } InformationOEM : WORD;
- ReservedToo : ARRAY[$28..$3B] OF BYTE;
- { 3C } NewExeHeaderOfs : LONGINT
- END;
- ExeHeaderOS2 = RECORD
- Signature : ARRAY[1..2] OF CHAR;
- LinkerMajorVers : BYTE;
- LinkerMinorVers : BYTE;
- EntryTableOfs : WORD;
- EntryTableSize : WORD;
- CRC : LONGINT;
- ModuleFlags : WORD;
- SegmentNoDGROUP : WORD;
- HeapSize : WORD;
- StackSize : WORD;
- EntryIP : WORD;
- EntryCS : WORD;
- EntrySP : WORD;
- EntrySS : WORD;
- SegmentTableEntries : WORD;
- ModuleRefEntries : WORD;
- NonResNameTableSize : WORD;
- SegTableOfs : WORD;
- ResourceTableOfs : WORD;
- ResNamesTableOfs : WORD;
- ModuleRefTableOfs : WORD;
- ImpNamesTableOfs : WORD;
- NonResNamesTableOfs : LONGINT;
- MovableEntryPoints : WORD;
- AlignmentUnitPower : WORD;
- ResourceTableEntries: WORD;
- TargetOS : BYTE;
- WindowsFlags : BYTE;
- FastLoadStart : WORD;
- FastLoadSize : WORD;
- Reserved : WORD;
- WindowsVers : WORD
- END;
- SegTableRec = RECORD
- Start : WORD;
- Size : WORD;
- Flags : WORD;
- MinSize : WORD
- END;
- FileOffset = LONGINT;
-
- PROCEDURE ReadOnly;
- INLINE($C6/$06/FileMode/$A0);
-
- PROCEDURE ReadWrite;
- INLINE($C6/$06/FileMode/$02);
-
- { ExeOfs returns the offset of the item V in the .EXE file of the currently }
- { running program. Use this to get the offset of a configuration record that }
- { is located in the .EXE file (remember that you must declare it as a typed }
- { constant to include it in the .EXE file) }
-
- {$IFDEF DPMI }
- FUNCTION ExeOfs(CONST V) : FileOffset;
- VAR
- HeaderDOS : ExeHeaderDOS;
- HeaderOS2 : ExeHeaderOS2;
- FIL : FILE;
- CodeSeg,Seg : WORD;
- SegTab : SegTableRec;
-
- BEGIN
- ReadOnly;
- ASSIGN(FIL,ParamStr(0)); RESET(FIL,1);
- BLOCKREAD(FIL,HeaderDOS,SizeOf(ExeHeaderDOS));
- IF HeaderDOS.Signature<>'MZ' THEN
- ExeOfs:=-1
- ELSE BEGIN
- SEEK(FIL,HeaderDOS.NewExeHeaderOfs);
- BLOCKREAD(FIL,HeaderOS2,SizeOf(ExeHeaderOS2));
- IF HeaderOS2.Signature<>'NE' THEN
- ExeOfs:=-1
- ELSE BEGIN
- ASM
- MOV BX,WORD PTR V+2
- MOV CX,SS
- CMP BX,CX
- JE @STACK
- XOR AX,AX
- VERW BX
- JZ @OUT
- MOV ES,BX
- MOV AX,ES:[0000h]
- JMP @OUT
- @STACK: MOV AX,HeaderOS2.EntrySS
- @OUT: MOV CodeSeg,AX
- END;
- IF CodeSeg<>0 THEN BEGIN
- SEEK(FIL,HeaderDOS.NewExeHeaderOfs+HeaderOS2.SegTableOfs+
- PRED(CodeSeg)*SizeOf(SegTableRec));
- BLOCKREAD(FIL,SegTab,SizeOf(SegTableRec)) END
- ELSE BEGIN
- SEEK(FIL,HeaderDOS.NewExeHeaderOfs+HeaderOS2.SegTableOfs);
- FOR Seg:=1 TO HeaderOS2.SegmentTableEntries DO BEGIN
- BLOCKREAD(FIL,SegTab,SizeOf(SegTableRec));
- IF (SegTab.Start>0) AND (SegTab.Flags AND $0001=$0001) THEN BREAK
- END
- END;
- ExeOfs:=SegTab.Start SHL HeaderOS2.AlignmentUnitPower+OFS(V)
- END
- END;
- CLOSE(FIL);
- ReadWrite
- END;
- {$ELSE }
- FUNCTION ExeOfs(CONST V) : FileOffset;
- VAR
- HeaderDOS : ExeHeaderDOS;
- FIL : FILE;
-
- BEGIN
- ReadOnly;
- ASSIGN(FIL,ParamStr(0)); RESET(FIL,1);
- BLOCKREAD(FIL,HeaderDOS,SizeOf(ExeHeaderDOS));
- CLOSE(FIL);
- ExeOfs:=(HeaderDOS.HeaderSizePara+(SEG(V)-(PrefixSeg+$0010)))*16+OFS(V)
- END;
- {$ENDIF }